<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>客户端外网IP实时监控</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/@fingerprintjs/fingerprintjs@3/dist/fp.min.js"></script>
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#165DFF',
                        secondary: '#36D399',
                        danger: '#F87272',
                        dark: '#1E293B',
                    },
                    fontFamily: {
                        inter: ['Inter', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }

            .text-shadow {
                text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
            }

            .card-shadow {
                box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
            }

            .pulse-animation {
                animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
            }

            @keyframes pulse {
                0%, 100% {
                    opacity: 1;
                }
                50% {
                    opacity: 0.5;
                }
            }
        }
    </style>
</head>
<body class="bg-gradient-to-br from-gray-50 to-gray-100 min-h-screen font-inter text-dark">
<div class="container mx-auto px-4 py-12 max-w-4xl">
    <header class="mb-10 text-center">
        <h1 class="text-[clamp(2rem,5vw,3rem)] font-bold text-primary mb-2 text-shadow">
            <i class="fa fa-globe mr-3"></i>客户端外网IP监控
        </h1>
        <p class="text-gray-600 text-lg">实时显示您的外网IP地址</p>
    </header>

    <main class="bg-white rounded-2xl p-6 md:p-8 card-shadow transform transition-all duration-300 hover:shadow-xl">
        <div class="flex flex-col items-center">
            <div class="w-full mb-8 bg-gray-50 rounded-xl p-6 border border-gray-200">
                <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
                    <i class="fa fa-info-circle text-primary mr-2"></i>您的外网IP信息
                </h2>
                <div id="ip-display"
                     class="font-mono text-lg bg-gray-100 p-4 rounded-lg min-h-[120px] overflow-auto border border-gray-200 transition-all duration-300">
                    <div class="flex items-center justify-center h-28 text-gray-400">
                        <i class="fa fa-spinner fa-spin mr-2"></i>正在获取IP信息...
                    </div>
                </div>
            </div>

            <div class="flex flex-wrap gap-4 justify-center">
                <button id="refresh-btn"
                        class="px-6 py-3 bg-primary text-white rounded-lg font-medium flex items-center transition-all duration-300 hover:bg-primary/90 transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-primary/50">
                    <i class="fa fa-refresh mr-2"></i>立即刷新
                </button>
                <button id="copy-btn"
                        class="px-6 py-3 bg-gray-200 text-gray-800 rounded-lg font-medium flex items-center transition-all duration-300 hover:bg-gray-300 transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-gray-400/50">
                    <i class="fa fa-copy mr-2"></i>复制IP
                </button>
            </div>

            <div id="status" class="mt-6 text-sm text-gray-500 flex items-center">
                <span id="connection-status" class="inline-block w-3 h-3 rounded-full bg-yellow-400 mr-2"></span>
                <span>正在获取IP...</span>
            </div>
        </div>
    </main>

    <footer class="mt-12 text-center text-gray-500 text-sm">
        <p>© 2025 IP监控系统 | 每30秒自动更新一次</p>
    </footer>
</div>

<script>
    document.addEventListener('DOMContentLoaded', async function () {
        const ipDisplay = document.getElementById('ip-display');
        const refreshBtn = document.getElementById('refresh-btn');
        const copyBtn = document.getElementById('copy-btn');
        const connectionStatus = document.getElementById('connection-status');
        const statusText = document.getElementById('status').querySelector('span:last-child');

        // 初始化 FingerprintJS
        const fp = await FingerprintJS.load();

        // 获取指纹数据
        const result = await fp.get();
        const visitorId = result.visitorId;
        // 打印浏览器指纹（visitorId）
        console.log('浏览器指纹 visitorId:', result.visitorId);

        let currentIp = '';
        let updateInterval;

        // 获取客户端唯一标识（简化版，实际项目可使用更可靠的方式）
        const clientId = localStorage.getItem('clientId') || generateRandomId();
        localStorage.setItem('clientId', clientId);

        // 生成随机ID
        function generateRandomId() {
            return 'client-' + Math.random().toString(36).substring(2, 10);
        }


        // 获取并显示IP信息
        async function fetchAndDisplayIp() {
            try {
                // 1. 先获取客户端外网IP
                connectionStatus.className = 'inline-block w-3 h-3 rounded-full bg-yellow-400 mr-2';
                statusText.textContent = '正在获取IP...';

            console.log('正在获取IP...: ' + visitorId);
                const reportResponse = await fetch('/api/getIpAddress?finger=' + visitorId, {
                    method: 'GET',
                    headers: {'Content-Type': 'application/json'},
                });

                const data = await reportResponse.json(); // 解析 JSON 数据
                // 获取到IP地址
                const ip = data.ip;
                displayIpInfo(ip);
                connectionStatus.className = 'inline-block w-3 h-3 rounded-full bg-green-500 mr-2';
                statusText.textContent = 'IP已更新';

                // 添加成功动画
                ipDisplay.classList.add('ring-2', 'ring-green-500');
                setTimeout(() => {
                    ipDisplay.classList.remove('ring-2', 'ring-green-500');
                }, 1000);

            } catch (error) {
                console.error('获取IP失败:', error);
                displayError(`获取IP失败: ${error.message}`);
                connectionStatus.className = 'inline-block w-3 h-3 rounded-full bg-red-500 mr-2';
                statusText.textContent = '获取IP失败，将重试';
            }
        }

        // 显示IP信息
        function displayIpInfo(ip) {
            ipDisplay.innerHTML = `
                    <div class="flex flex-col items-center justify-center h-28">
                        <div class="text-2xl md:text-3xl font-bold text-primary mb-2 break-all">${ip}</div>
                        <div class="text-sm text-gray-500">这是您的设备访问公网时的出口IP地址</div>
                    </div>
                `;
        }

        // 显示错误信息
        function displayError(message) {
            ipDisplay.innerHTML = `
                    <div class="flex flex-col items-center justify-center h-28 text-gray-500">
                        <i class="fa fa-exclamation-triangle text-xl mb-2 text-red-500"></i>
                        <p>${message}</p>
                    </div>
                `;
        }

        // 刷新按钮事件
        refreshBtn.addEventListener('click', function () {
            clearInterval(updateInterval); // 暂停自动更新
            fetchAndDisplayIp();
            // 重新启动自动更新
            startAutoUpdate();
        });

        // 复制按钮事件
        copyBtn.addEventListener('click', function () {
            if (currentIp) {
                navigator.clipboard.writeText(currentIp)
                    .then(() => {
                        showNotification('IP已复制到剪贴板');
                    })
                    .catch(err => {
                        console.error('复制失败:', err);
                        showNotification('复制失败，请手动复制', true);
                    });
            }
        });

        // 显示通知
        function showNotification(message, isError = false) {
            const notification = document.createElement('div');
            notification.className = `fixed top-4 right-4 px-6 py-3 rounded-lg shadow-lg z-50 transform transition-all duration-300 ${isError ? 'bg-red-500 text-white' : 'bg-green-500 text-white'}`;
            notification.textContent = message;

            document.body.appendChild(notification);

            // 淡入效果
            setTimeout(() => {
                notification.style.transform = 'translateY(0)';
                notification.style.opacity = '1';
            }, 10);

            // 3秒后淡出
            setTimeout(() => {
                notification.style.transform = 'translateY(-10px)';
                notification.style.opacity = '0';
                setTimeout(() => {
                    document.body.removeChild(notification);
                }, 300);
            }, 3000);
        }

        // 启动自动更新（每30秒一次）
        function startAutoUpdate() {
            updateInterval = setInterval(fetchAndDisplayIp, 2000);
        }

        // 初始化
        fetchAndDisplayIp();
        startAutoUpdate();
    });
</script>
</body>
</html>